function nmat2mft(nmat, ofname, tpq, tempo, tsig1, tsig2, insts)
% function nmat2mft(nmat, ofname, tpq, tempo, tsig1, tsig2, insts)
%
% Converts a notematrix to a MIDI text file.
%
% Input: 
%   nmat     [mat] - The notematrix
%  (Optional)
%   ofnam    [str] - Output filename (*.mid)
%   tpq      [num] - Ticks per quarter note (default 120)
%   tempo    [num] - Desired tempo in beats per minute (default 100)
%   tsig1    [num] - Time-signature numerator, e.g. 6/8 -> tsig1 = 6 (default 4)
%   tsig2    [num] - Time-signature denominator, e.g. 6/8 -> tsig2 = 8 (default 4)
%   insts = program number to use for this track, [] means none
%
% Output: (MIDI text file)
%
% Remarks: TEXT2MIDI converter needs to be handled differently in PC and Mac.
%
% Example: nmat2mft(nmat,'demo.txt', 120, 80, 4, 4);
%

%  Author		Date
% 30.2.2003	11:40	TE	Created under MATLAB 5.3 (PC)
% Part of the MIDI Toolbox Software Package, Copyright 2002, University of Jyv�skyl�, Finland
% See License.txt
%
% Modified on 02/17/2009 by Graham Grindlay (grindlay@ee.columbia.edu) to
% add support for different instruments per channel via program change
% messages.

% Copyright (C) 2009-2029 Graham Grindlay (grindlay@ee.columbia.edu)
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.

if isempty(nmat), return; end

if nargin < 2
    ofname = 'temp.txt'; 
    disp('Output filename missing, wrote results to "temp.txt" file'); 
end
if nargin < 3 
    tpq=120;
end
if nargin < 4 
    tempo=100; 
end
if nargin < 5 
    tsig1=4; 
end
if nargin < 6 
    tsig2=4; 
    disp('Default parameters used'); 
end
if nargin < 7 
    insts = []; 
end

fid = fopen(ofname,'w');
ch = mchannels(nmat);
NCH = length(ch)+1;
ninst = length(insts);

% make sure that number of channels and instruments match up
if length(ch) > ninst && ~isempty(insts)
    warning(['More channels in nmat than instrument numbers - ' ...
             'repeating last instrument number.']);
    insts = [insts insts(end)*ones(1, length(ch)-ninst)];
elseif length(ch) < ninst  && ~isempty(insts)
    warning(['Fewer channels in nmat than instrument numbers - ' ...
             'removing last instrument numbers.']);
    insts = insts(1:length(ch));
end

% write header
fprintf(fid,'MFile 1 %d %d\r\n', NCH, tpq);

% write conductor track
fprintf(fid,'MTrk\r\n');
fprintf(fid,'0 TimeSig %d/%d 24 8\r\n', tsig1, tsig2);
fprintf(fid,'0 Tempo %d\r\n', floor(1000000*60/tempo));
fprintf(fid,'0 Meta TrkEnd\r\n');
fprintf(fid,'TrkEnd\r\n');

for k=1:length(ch)
    tmp = [];
    nm = getmidich(nmat, ch(k));
    ontime=floor(onset(nm)*tpq);
    offtime = floor((onset(nm)+dur(nm))*tpq);
    p = pitch(nm);
    v = velocity(nm);
    for m=1:size(nm,1)
        tmp = [tmp; ontime(m) ch(k) p(m) v(m)];
        tmp = [tmp; offtime(m) ch(k) p(m) 0];
    end
    
    [Y,I] = sort(tmp(:,1));
    tmp2 = tmp(I,:);
    
    fprintf(fid,'MTrk\r\n');
    
    % GCG - 02/19/2009
    if ~isempty(insts)
        fprintf(fid, '0 PrCh ch=%d p=%d\r\n', ch(k), insts(k));
    end
    
    for m=1:size(tmp2,1)
        fprintf(fid,'%d On ch=%d n=%d v=%d\r\n', tmp2(m,1), tmp2(m,2), tmp2(m,3), tmp2(m,4));
    end
    
    fprintf(fid,'%d Meta TrkEnd\r\n', tmp2(end,1));
    fprintf(fid,'TrkEnd\r\n');
end

status = fclose(fid);
